/*!
 * \file MatchEngine.h
 * \project WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 撮合引擎定义文件
 * 
 * \details 本文件定义了MatchEngine类和IMatchSink接口，用于在WonderTrader回测框架中模拟真实的订单撮合过程。
 *          撮合引擎的主要功能包括：
 *          - 模拟限价订单簿(LOB)的维护和更新
 *          - 基于实时行情数据进行订单撮合
 *          - 处理买入、卖出和撤销订单操作
 *          - 生成成交回报和订单状态回报
 *          - 支持自定义撤单率配置
 *          - 提供完整的订单生命周期管理
 */
#pragma once
#include <stdint.h>
#include <map>
#include <vector>
#include <functional>
#include <string.h>

#include "../Includes/WTSMarcos.h"
#include "../Includes/WTSCollection.hpp"
#include "../Includes/FasterDefs.h"

NS_WTP_BEGIN
class WTSTickData;
class WTSVariant;
NS_WTP_END

USING_NS_WTP;

typedef std::vector<uint32_t> OrderIDs; /*!< 订单ID列表类型定义 */

typedef WTSHashMap<std::string>	WTSTickCache; /*!< tick数据缓存类型定义 */

/*!
 * \class IMatchSink
 * \brief 撮合结果接收接口
 * 
 * \details IMatchSink接口定义了撮合引擎向外部通知撮合结果的回调方法。
 *          实现此接口的类可以接收以下事件：
 *          - 成交回报：订单成交时的详细信息
 *          - 订单回报：订单状态变更时的信息
 *          - 委托确认：订单提交后的确认信息
 */
class IMatchSink
{
public:
	/*!
	 * \brief 处理成交回报
	 * \param localid 本地订单ID
	 * \param stdCode 标准合约代码
	 * \param isBuy 是否为买入方向
	 * \param vol 成交数量，如果没有特殊标记，通过isBuy确定是买入还是卖出
	 * \param fireprice 触发价格
	 * \param price 成交价格
	 * \param ordTime 订单时间
	 */
	virtual void handle_trade(uint32_t localid, const char* stdCode, bool isBuy, double vol, double fireprice, double price, uint64_t ordTime) = 0;

	/*!
	 * \brief 处理订单回报
	 * \param localid 本地订单ID
	 * \param stdCode 标准合约代码
	 * \param isBuy 是否为买入方向
	 * \param leftover 剩余数量
	 * \param price 委托价格
	 * \param isCanceled 是否已撤销
	 * \param ordTime 订单时间
	 */
	virtual void handle_order(uint32_t localid, const char* stdCode, bool isBuy, double leftover, double price, bool isCanceled, uint64_t ordTime) = 0;

	/*!
	 * \brief 处理委托确认回报
	 * \param localid 本地订单ID
	 * \param stdCode 标准合约代码
	 * \param bSuccess 委托是否成功
	 * \param message 返回消息
	 * \param ordTime 订单时间
	 */
	virtual void handle_entrust(uint32_t localid, const char* stdCode, bool bSuccess, const char* message, uint64_t ordTime) = 0;
};

typedef std::function<void(double)> FuncCancelCallback; /*!< 撤单回调函数类型 */

/*!
 * \class MatchEngine
 * \brief 撮合引擎类
 * 
 * \details MatchEngine是WonderTrader回测框架中的核心撮合组件，负责模拟真实交易所的订单撮合过程。
 *          主要功能包括：
 *          - 维护每个合约的限价订单簿(Limit Order Book)
 *          - 根据实时行情数据进行订单撮合
 *          - 处理订单的提交、撤销和成交
 *          - 计算订单在队列中的位置
 *          - 支持市价和限价订单
 *          - 提供灵活的撤单率配置
 * 
 * \note 此类是回测环境中订单执行的核心，确保回测结果的真实性和准确性
 * \see IMatchSink
 */
class MatchEngine
{
public:
	/*!
	 * \brief 构造函数
	 */
	MatchEngine() : _tick_cache(NULL),_cancelrate(0), _sink(NULL)
	{

	}

private:
	/*!
	 * \brief 触发指定合约的订单撮合
	 * \param stdCode 标准合约代码
	 * \param to_erase 需要擦除的订单ID列表
	 */
	void	fire_orders(const char* stdCode, OrderIDs& to_erase);
	
	/*!
	 * \brief 根据最新tick数据撮合订单
	 * \param curTick 当前tick数据
	 * \param to_erase 需要擦除的订单ID列表
	 */
	void	match_orders(WTSTickData* curTick, OrderIDs& to_erase);
	
	/*!
	 * \brief 更新限价订单簿
	 * \param curTick 当前tick数据
	 */
	void	update_lob(WTSTickData* curTick);

	/*!
	 * \brief 获取指定合约的最新tick数据
	 * \param stdCode 标准合约代码
	 * \return 最新tick数据指针
	 */
	inline WTSTickData*	grab_last_tick(const char* stdCode);

public:
	/*!
	 * \brief 初始化撮合引擎
	 * \param cfg 配置参数
	 */
	void	init(WTSVariant* cfg);

	/*!
	 * \brief 注册撮合结果接收器
	 * \param sink 撮合结果接收器指针
	 */
	void	regisSink(IMatchSink* sink) { _sink = sink; }

	/*!
	 * \brief 清理撮合引擎状态
	 */
	void	clear();

	/*!
	 * \brief 处理tick数据
	 * \param stdCode 标准合约代码
	 * \param curTick 当前tick数据
	 */
	void	handle_tick(const char* stdCode, WTSTickData* curTick);

	/*!
	 * \brief 提交买入订单
	 * \param stdCode 标准合约代码
	 * \param price 订单价格
	 * \param qty 订单数量
	 * \param curTime 当前时间
	 * \return 订单ID列表
	 */
	OrderIDs	buy(const char* stdCode, double price, double qty, uint64_t curTime);
	
	/*!
	 * \brief 提交卖出订单
	 * \param stdCode 标准合约代码
	 * \param price 订单价格
	 * \param qty 订单数量
	 * \param curTime 当前时间
	 * \return 订单ID列表
	 */
	OrderIDs	sell(const char* stdCode, double price, double qty, uint64_t curTime);
	
	/*!
	 * \brief 撤销指定订单
	 * \param localid 本地订单ID
	 * \return 撤销的数量
	 */
	double		cancel(uint32_t localid);
	
	/*!
	 * \brief 撤销指定合约的订单
	 * \param stdCode 标准合约代码
	 * \param isBuy 是否为买入方向
	 * \param qty 撤销数量
	 * \param cb 撤单回调函数
	 * \return 撤销的订单ID列表
	 */
	virtual OrderIDs cancel(const char* stdCode, bool isBuy, double qty, FuncCancelCallback cb);

private:
	/*!
	 * \struct _OrderInfo
	 * \brief 订单信息结构
	 */
	typedef struct _OrderInfo
	{
		char		_code[32];		/*!< 合约代码 */
		bool		_buy;			/*!< 是否为买入方向 */
		double		_qty;			/*!< 订单数量 */
		double		_left;			/*!< 剩余数量 */
		double		_traded;		/*!< 已成交数量 */
		double		_limit;			/*!< 限价 */
		double		_price;			/*!< 价格 */
		uint32_t	_state;			/*!< 订单状态 */
		uint64_t	_time;			/*!< 订单时间 */
		double		_queue;			/*!< 队列位置 */
		bool		_positive;		/*!< 是否为正向订单 */

		/*!
		 * \brief 构造函数
		 */
		_OrderInfo()
		{
			memset(this, 0, sizeof(_OrderInfo));
		}
	} OrderInfo;

	typedef faster_hashmap<uint32_t, OrderInfo> Orders; /*!< 订单映射表类型 */
	Orders	_orders;	/*!< 订单映射表 */

	typedef std::map<uint32_t, double>	LOBItems; /*!< 限价订单簿条目类型 */

	/*!
	 * \struct _LmtOrdBook
	 * \brief 限价订单簿结构
	 */
	typedef struct _LmtOrdBook
	{
		LOBItems	_items;		/*!< 订单簿条目 */
		uint32_t	_cur_px;	/*!< 当前价格 */
		uint32_t	_ask_px;	/*!< 卖一价格 */
		uint32_t	_bid_px;	/*!< 买一价格 */

		/*!
		 * \brief 清理订单簿
		 */
		void clear()
		{
			_items.clear();
			_cur_px = 0;
			_ask_px = 0;
			_bid_px = 0;
		}

		/*!
		 * \brief 构造函数
		 */
		_LmtOrdBook()
		{
			_cur_px = 0;
			_ask_px = 0;
			_bid_px = 0;
		}
	} LmtOrdBook;
	
	typedef faster_hashmap<std::string, LmtOrdBook> LmtOrdBooks; /*!< 限价订单簿映射表类型 */
	LmtOrdBooks	_lmt_ord_books;		/*!< 限价订单簿映射表 */

	IMatchSink*	_sink;				/*!< 撮合结果接收器 */

	double			_cancelrate;	/*!< 撤单率 */
	WTSTickCache*	_tick_cache;	/*!< tick数据缓存 */
};

